package com.tbr.blockchain.model;

import com.alibaba.fastjson.JSON;
import com.sun.org.apache.xpath.internal.SourceTree;
import com.tbr.blockchain.security.CryptoUtil;
import com.tbr.blockchain.security.RSACoder;

public class Transaction implements Cloneable {
    private String id;
    private TransactionInput txIn;
    private TransactionOutput txOut;

    @Override
    public Object clone(){
        Transaction o=null;
        try {
            o = (Transaction) super.clone();
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
        return o;
    }


    public Transaction() {
    }

    public Transaction(String id, TransactionInput txIn, TransactionOutput txOut) {
        this.id = id;
        this.txIn = txIn;
        this.txOut = txOut;
    }

//    是否是系统生成区块的奖励交易
    public boolean coinBaseTx(){
        return txIn.getTxId().equals("0")&&getTxIn().getValue()==-1;
    }


//    生成交易副本
    public Transaction clonTx(){
        TransactionInput transactionInput=new TransactionInput(txIn.getTxId(),txIn.getValue(),null,null);
        TransactionOutput transactionOutput=new TransactionOutput(txOut.getValue(), txOut.getPublicKeyHash());
        return new Transaction(id,transactionInput,transactionOutput);
    }

    public String hash(){
        return CryptoUtil.SHA256(JSON.toJSONString(this));
    }

//    验证交易签名
    public boolean verify(Transaction preTx){
        if(coinBaseTx()){
            return true;
        }

        System.out.println(preTx.getId());
        System.out.println(txIn.getTxId());
        if(!preTx.getId().equals(txIn.getTxId())){
            System.err.println("交易签名失败,当前交易的输入与上一笔交易的输出不匹配");
        }

        Transaction txClone=clonTx();
        txClone.getTxIn().setPublicKey(preTx.getTxOut().getPublicKeyHash());

        boolean result=false;
        try {
            result=RSACoder.publicdecrypt(txIn.getSignature(),txIn.getPublicKey(),txClone.hash());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;

    }

//    私钥生成交易签名

    public void sign(String privateKey,Transaction preTx){
        if(coinBaseTx()){
            return;
        }

        if(!preTx.getId().equals(getTxIn().getTxId())){
            System.out.println("交易签名失败,当前交易的输入与上一笔交易的输出不匹配");
        }

        Transaction txClone=clonTx();
        txClone.getTxIn().setPublicKey(preTx.getTxOut().getPublicKeyHash());
        String sign="";
        try {
            sign= RSACoder.privateSignture(txClone.hash(),privateKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
        txIn.setSignature(sign);
    }

    /**
     * 获取
     * @return id
     */
    public String getId() {
        return id;
    }

    /**
     * 设置
     * @param id
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * 获取
     * @return txIn
     */
    public TransactionInput getTxIn() {
        return txIn;
    }

    /**
     * 设置
     * @param txIn
     */
    public void setTxIn(TransactionInput txIn) {
        this.txIn = txIn;
    }

    /**
     * 获取
     * @return txOut
     */
    public TransactionOutput getTxOut() {
        return txOut;
    }

    /**
     * 设置
     * @param txOut
     */
    public void setTxOut(TransactionOutput txOut) {
        this.txOut = txOut;
    }

    public String toString() {
        return "Transaction{id = " + id + ", txIn = " + txIn + ", txOut = " + txOut + "}";
    }
}
